package admin

import (
	"baokaobang/conf"
	"baokaobang/datasourse"
	"baokaobang/models"
	"baokaobang/utils"
	"encoding/json"
	"fmt"
	"github.com/360EntSecGroup-Skylar/excelize"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"strings"
)

type Rank struct {
	Ctx iris.Context
}

type CreateRank struct {
	Id       string `json:"id"`
	Year     int `json:"year"`
	Subject  int `json:"subject"`
	Score    string `json:"score"`
	ScoreNum string `json:"scoreNum"`
	Section  string `json:"section"`
}

type ExcelCreate struct {
	Year     int    `json:"year"`
	Subject  int    `json:"subject"`
	ExcelUrl string `json:"excelUrl"`
}

type RankListParam struct {
	Year    int `json:"year"`
	Subject int `json:"subject"`
	PerPage int `json:"perPage"`
	CurPage int `json:"curPage"`
}

func (c *Rank) OptionsExcel() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *Rank) PostExcel() interface{} {
	excelCreate := ExcelCreate{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接受请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &excelCreate)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("参数解析出错:%s", err.Error()), "")
	}

	if excelCreate.Year <= 0 {
		return utils.CommonRes(1000, "请选择年份", "")
	}
	if excelCreate.Subject <= 0 {
		return utils.CommonRes(1000, "请选择科目", "")
	}
	if len(excelCreate.ExcelUrl) <= 0 {
		return utils.CommonRes(1000, "请上传excel文件", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	sess := db.NewSession()
	defer sess.Close()
	err = sess.Begin()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("数据库事务开启失败：%s", err.Error()), "")
	}

	filePath := fmt.Sprintf("%s%s", conf.UploadPrefix.Backend, excelCreate.ExcelUrl)
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("上传的文件无法打开:%s", err.Error()), "")
	}

	base := 0
	score := 0
	scoreNum := 0
	section := ""

	sheetList := f.GetSheetMap()
	for _, sheet := range sheetList {
		rows := f.GetRows(sheet)
		for i, row := range rows {
			if i == 0 {
				continue
			}
			score = utils.Atoi(row[0])
			scoreNum = utils.Atoi(row[1])
			if score <= 0 {
				return utils.CommonRes(1000, "分数异常，请检查excel文件中分数字段", "")
			}
			section = fmt.Sprintf("%d~%d", base+1, base+scoreNum)
			base = base + scoreNum

			rank := new(models.Rank)
			rank.Year = excelCreate.Year
			rank.Subject = excelCreate.Subject
			rank.Score = score
			rank.Section = section
			rank.ScoreNum = scoreNum
			_, err = db.InsertOne(rank)
			if err != nil {
				return utils.CommonRes(1000, fmt.Sprintf("数据导入失败：%s", err.Error()), "")
			}
		}
	}
	sess.Commit()

	return utils.CommonRes(20000, "数据导入成功", "")
}

func (c *Rank) OptionsEdit() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *Rank) PostEdit() interface{} {
	createRank := CreateRank{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &createRank)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错:%s", err.Error()), "")
	}

	if len(createRank.Id) <= 0 {
		return utils.CommonRes(1000, "请提供位次id", "")
	}
	if createRank.Year <= 0 {
		return utils.CommonRes(1000, "请选择年份", "")
	}
	if createRank.Subject <= 0 {
		return utils.CommonRes(1000, "请选择科目", "")
	}
	if len(createRank.Score) <= 0 {
		return utils.CommonRes(1000, "请输入分数", "")
	}
	if len(createRank.ScoreNum) <= 0 {
		return utils.CommonRes(1000, "请输入同分人数", "")
	}
	if len(createRank.Section) <= 0 {
		return utils.CommonRes(1000, "请输入位次区间", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库:%s", err.Error()), "")
	}

	updateData := map[string]interface{}{
		"year":      createRank.Year,
		"subject":   createRank.Subject,
		"score":     createRank.Score,
		"score_num": createRank.ScoreNum,
		"section":   createRank.Section,
	}

	_, err = db.Table(new(models.Rank)).ID(createRank.Id).Update(updateData)
	if err != nil {
		return utils.CommonRes(1000, "操作失败", "")
	}

	return utils.CommonRes(20000, "操作成功", "")
}

func (c *Rank) OptionsDetail() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *Rank) PostDetail() interface{} {
	editParam := utils.EditParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &editParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错:%s", err.Error()), "")
	}

	if len(editParam.Id) <= 0 {
		return utils.CommonRes(1000, "请提供位次id", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库:%s", err.Error()), "")
	}

	rank := new(models.Rank)
	ok, err := db.ID(editParam.Id).Get(rank)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("信息获取失败:%s", err.Error()), "")
	}
	if !ok {
		return utils.CommonRes(1000, "信息获取失败", "")
	}

	return utils.CommonRes(20000, "信息获取成功", rank)
}

func (c *Rank) OptionsList() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *Rank) PostList() interface{} {
	rankListParam := RankListParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接收请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &rankListParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("解析请求参数出错:%s", err.Error()), "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库:%s", err.Error()), "")
	}

	start := (rankListParam.CurPage - 1) * rankListParam.PerPage
	rankList := make([]models.Rank, 0)
	sess := db.Limit(rankListParam.PerPage, start)
	if rankListParam.Year > 0 {
		sess = sess.Where("year = ?", rankListParam.Year)
	}
	if rankListParam.Subject > 0 {
		sess = sess.Where("subject = ?", rankListParam.Subject)
	}
	err = sess.Find(&rankList)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取位次列表:%s", err.Error()), "")
	}

	countSess := db.Where("id > ?", 0)
	if rankListParam.Year > 0 {
		countSess = countSess.Where("year = ?", rankListParam.Year)
	}
	if rankListParam.Subject > 0 {
		countSess = countSess.Where("subject = ?", rankListParam.Subject)
	}
	total, err := countSess.Count(new(models.Rank))
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法获取位次列表:%s", err.Error()), "")
	}

	for i, item := range rankList {
		rankList[i].SubjectShow = models.RankSubject[item.Subject]
	}

	data := map[string]interface{}{
		"total": total,
		"list":  rankList,
	}

	return utils.CommonRes(20000, "成功获取位次列表", data)
}

func (c *Rank) OptionsDel() mvc.Response {
	return mvc.Response{
		Code: 204,
	}
}

func (c *Rank) PostDel() interface{} {
	delParam := utils.DelParam{}
	content, err := c.Ctx.GetBody()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("接受请求参数出错:%s", err.Error()), "")
	}
	err = json.Unmarshal(content, &delParam)
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("参数解析出错：%s", err.Error()), "")
	}

	if len(delParam.Ids) <= 0 {
		return utils.CommonRes(1000, "请提供要删除项的id", "")
	}

	db, err := datasourse.NewMasterOrm()
	if err != nil {
		return utils.CommonRes(1000, fmt.Sprintf("无法连接数据库：%s", err.Error()), "")
	}

	ids := strings.Split(delParam.Ids, ",")
	for _, id := range ids {
		rank := new(models.Rank)
		db.ID(id).Get(rank)
		db.ID(id).Delete(rank)
	}

	return utils.CommonRes(20000, "操作成功", "")
}
